home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #11 / Amiga Plus CD - 2004 - No. 11.iso / AmiSoft / Util / conv / Acvt.lha / Acvt 1.07 / sources / adsk_di.cpp < prev    next >
C/C++ Source or Header  |  2001-03-08  |  5KB  |  272 lines

  1. //    This program is free software; you can redistribute it and/or modify
  2. //    it under the terms of the GNU General Public License as published by
  3. //    the Free Software Foundation; either version 2 of the License, or
  4. //    any later version.
  5. //
  6. //    This program is distributed in the hope that it will be useful,
  7. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9. //    GNU General Public License for more details.
  10. //
  11. //    You should have received a copy of the GNU General Public License
  12. //    along with this program; if not, write to the Free Software
  13. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. //
  15.  
  16. #include "adsk_di.h"
  17. #include "autil.h"
  18. #include "cfile.h"
  19.  
  20. BYTE di_crc( BYTE* pbt, int iLen )
  21. {
  22.     WORD crc = 0;
  23.  
  24.     while( iLen-- )
  25.     {
  26.         crc += *( pbt++ );
  27.         if( crc >= 0x100 )
  28.             crc -= 0xFF;
  29.     }
  30.     
  31.     return crc;
  32. }
  33.  
  34. CDi::CDi() : ADisk()
  35. {
  36.     #ifdef _MEMORY_DUMP_
  37.         printf( "CDi constructed: %p\n", this );
  38.     #endif
  39. }
  40.  
  41. CDi::~CDi()
  42. {
  43.     #ifdef _MEMORY_DUMP_
  44.         printf( "CDi destructed: %p\n", this );
  45.     #endif
  46. }
  47.  
  48. #ifndef __CDISK_NOLOAD__
  49. BOOL CDi::Load( char* szFname, BOOL bRepair, BOOL bRepairAuto )
  50. {
  51.     m_iErrorCode = 0;
  52.  
  53.     CFile cf;
  54.     if ( !cf.Open( szFname ) )
  55.     {
  56.         sprintf( m_szLastError, "DI: Can't open '%s'", szFname );
  57.         m_iErrorCode = CDISK_ERROR_CANT_OPEN;
  58.         return FALSE;
  59.     }
  60.  
  61.     strcpy( m_szFname, szFname );
  62.  
  63.     WORD wMagic = cf.readLEw();
  64.  
  65.     if ( wMagic != 18756 )    //'DI'
  66.     {
  67.         sprintf( m_szLastError, "DI: File '%s' is not an DI file!", szFname );
  68.         return FALSE;
  69.     }
  70.  
  71.     BYTE btVerLo = cf.readb();
  72.     BYTE btVerHi = cf.readb();
  73.  
  74.     if( ( btVerLo != 0x20 ) || ( btVerHi != 0x02 ) )
  75.     {
  76.         sprintf( m_szLastError, "DI: The file '%s' has strange version!\n"
  77.             "This program can't work with it now.\n"
  78.             "Send the file for the analysis.", szFname );
  79.         m_iErrorCode = CDI_FORMAT_VIOLATED;
  80.         return FALSE;
  81.     }
  82.  
  83.     int iMax = 200;
  84.     while( iMax-- )
  85.     {
  86.         if( ! cf.readb() )
  87.             break;
  88.     }
  89.  
  90.     if( !iMax )
  91.     {
  92.         sprintf( m_szLastError, "DI: Runaway in header ('%s')", szFname );
  93.         m_iErrorCode = CDI_FORMAT_VIOLATED;
  94.         return FALSE;
  95.     }
  96.  
  97.     //todo: this need the documentation! Is it number of sides?
  98.     //BYTE btUnk1 = 
  99.     cf.readb();
  100.  
  101.     BYTE btTracks = cf.readb();
  102.     WORD wSectorsPerTrack = cf.readBEw();
  103.  
  104.     //todo: are these the flags?
  105.     //WORD wUnk2 = 
  106.     //cf.readBEw();
  107.     BYTE btSides = cf.readb() + 1;
  108.     cf.readb();
  109.     
  110.     WORD wSectorSize = cf.readBEw();
  111.  
  112.     //todo: and what about this?
  113.     //BYTE btUnk3 = 
  114.     cf.readb();
  115.  
  116.     switch( wSectorSize )
  117.     {
  118.         case 0x80:
  119.         case 0x100:
  120.             break;
  121.  
  122.         default:
  123.         {
  124.             sprintf( m_szLastError, "DI: Invalid sector size: %04X", wSectorSize );
  125.             m_iErrorCode = CDI_FORMAT_VIOLATED;
  126.             return FALSE;
  127.         }
  128.     }
  129.  
  130.     DISK_GEOMETRY dg;
  131.  
  132.     dg.iSides = btSides;
  133.     dg.iTracks = btTracks;
  134.     dg.iSectorsPerTrack = wSectorsPerTrack;
  135.     dg.iBytesPerSector = wSectorSize;
  136.  
  137.     if ( !Format( &dg ) )
  138.         return FALSE;
  139.  
  140.     BYTE abtBuff[ 0x100 ];
  141.     memset( abtBuff, 0, 0x100 );
  142.  
  143.     int iSectors = m_geometry.iSectors;
  144.  
  145.     BYTE* pBuf = new BYTE[ iSectors ];
  146.     cf.Read( pBuf, iSectors );
  147.  
  148.     BYTE* p = pBuf;
  149.  
  150.     for( int i = 0; i < iSectors; i++ )
  151.     {
  152.         if( *p )
  153.         {
  154.             int iSecSize = ( i < 3 ) ? 0x80 : wSectorSize;
  155.  
  156.             int iRead;
  157.  
  158.             cf.Read( abtBuff, iSecSize, &iRead );
  159.  
  160.             if ( iRead != iSecSize )
  161.             {
  162.                 sprintf( m_szLastError, "DI: Read error. File truncated?" );
  163.                 delete [] pBuf;
  164.                 cf.Close();
  165.                 m_iErrorCode = CDI_FORMAT_VIOLATED;
  166.                 return FALSE;
  167.             }
  168.  
  169.             BYTE crc = di_crc( abtBuff, iSecSize );
  170.  
  171.             if( *p != crc )
  172.             {
  173.                 sprintf( m_szLastError, "DI: Sector checksum failed: Sector %d Given: %02X Computed: %02X", i + 1, *p, crc );
  174.                 delete [] pBuf;
  175.                 cf.Close();
  176.                 m_iErrorCode = CDI_FORMAT_VIOLATED;
  177.                 return FALSE;
  178.             }
  179.  
  180.             WriteSector( i + 1, abtBuff );
  181.         }
  182.         p++;
  183.     }
  184.  
  185.     delete [] pBuf;
  186.  
  187.     cf.Close();
  188.     return TRUE;
  189.  
  190. }
  191.  
  192. #endif
  193.  
  194. #ifdef __CDISK_SAVE__
  195.  
  196. char szDIhd[] = "Jindroush's DI class v1.00";
  197. //char szDIhd[] = "XL/ST-link 2.2.0› ";
  198.  
  199. BOOL CDi::Save( char* szOutFile, BOOL bOverWrite )
  200. {
  201.     if( ( m_geometry.iTracks > 0xFF ) ||
  202.         ( m_geometry.iSectorsPerTrack > 0xFFFF ) ||
  203.         ( m_geometry.iSides > 2 ) )
  204.     {
  205.         sprintf( m_szLastError, "DI: Can't create such file! Is it possible? :-)" );
  206.         return FALSE;
  207.     }
  208.  
  209.     CFile cf;
  210.  
  211.     if ( !bOverWrite && !access( szOutFile, F_OK ) )
  212.     {
  213.         sprintf( m_szLastError, "DI: File already exists! '%s'", szOutFile );
  214.         return FALSE;
  215.     }
  216.  
  217.     if ( !cf.Create( szOutFile ) )
  218.     {
  219.         sprintf( m_szLastError, "DI: Can't create '%s'", szOutFile );
  220.         return FALSE;
  221.     }
  222.  
  223.     cf.writeb( 'D' );
  224.     cf.writeb( 'I' );
  225.     cf.writeb( 0x20 );
  226.     cf.writeb( 0x02 );
  227.  
  228.     cf.Write( szDIhd, strlen( szDIhd ) + 1 );
  229.  
  230.     cf.writeb( 1 );
  231.     cf.writeb( m_geometry.iTracks );
  232.     cf.writeBEw( m_geometry.iSectorsPerTrack );
  233.     cf.writeb( m_geometry.iSides - 1 );
  234.     cf.writeb( 0 );
  235.     cf.writeBEw( m_geometry.iBytesPerSector );
  236.     cf.writeb( 0 );
  237.  
  238.     BYTE abtBuff[ 0x100 ];
  239.     memset( abtBuff, 0, 0x100 );
  240.  
  241.     BYTE* pBuf = new BYTE[ m_geometry.iSectors ];
  242.  
  243.     for( int i = 0; i < m_geometry.iSectors; i++ )
  244.     {
  245.         int iSecSize = ( i < 3 ) ? 0x80 : m_geometry.iBytesPerSector;
  246.  
  247.         ReadSector( abtBuff, i + 1 );
  248.         pBuf[ i ] = di_crc( abtBuff, iSecSize );
  249.     }
  250.  
  251.     cf.Write( pBuf, m_geometry.iSectors );
  252.  
  253.     for( int i = 0; i < m_geometry.iSectors; i++ )
  254.     {
  255.         int iSecSize = ( i < 3 ) ? 0x80 : m_geometry.iBytesPerSector;
  256.  
  257.         ReadSector( abtBuff, i + 1 );
  258.         if( pBuf[ i ] || !IsBlockEmpty( abtBuff, iSecSize ) )
  259.         {
  260.             cf.Write( abtBuff, iSecSize );
  261.         }
  262.     }
  263.  
  264.     delete [] pBuf;
  265.  
  266.     cf.Close();
  267.  
  268.     return TRUE;
  269. }
  270.  
  271. #endif //__CDISK_WRITE__
  272.